package com.yunb.redisbase.advtypes;

import com.google.common.hash.Funnels;
import com.google.common.hash.Hashing;
import com.google.common.primitives.Longs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;

import java.nio.charset.Charset;

/*仿Google的布隆过滤器实现*/
@Component
public class RedisBloomFilter {

    public final static String RS_BF_NS = "rbf:";
    private int numApproxElements; /*预估元素数量*/
    private double fpp; /*可接受的最大误差*/
    private int numHashFunctions; /*自动计算的hash函数个数*/
    private int bitmapLength; /*自动计算的最优Bitmap长度*/

    @Autowired
    private JedisPool jedisPool;

    /**
     * 构造布隆过滤器
     * @param numApproxElements 预估元素数量
     * @param fpp 可接受的最大误差
     * @return
     */
    //TODO

    /**
     * 计算一个元素值哈希后映射到Bitmap的哪些bit上
     * 用两个hash函数来模拟多个hash函数的情况
     *     * @param element 元素值
     * @return bit下标的数组
     */
    //TODO

    /**
     * 插入元素
     *
     * @param key       原始Redis键，会自动加上前缀
     * @param element   元素值，字符串类型
     * @param expireSec 过期时间（秒）
     */
    //TODO

    /**
     * 检查元素在集合中是否（可能）存在
     *
     * @param key     原始Redis键，会自动加上前缀
     * @param element 元素值，字符串类型
     */
//    public boolean mayExist(String key, String element) {
//        if (key == null || element == null) {
//            throw new RuntimeException("键值均不能为空");
//        }
//        String actualKey = RS_BF_NS.concat(key);
//        boolean result = false;
//
//        try (Jedis jedis = jedisPool.getResource()) {
//            try (Pipeline pipeline = jedis.pipelined()) {
//                for (long index : getBitIndices(element)) {
//                    pipeline.getbit(actualKey, index);
//                }
//                result = !pipeline.syncAndReturnAll().contains(false);
//            } catch (Exception ex) {
//                ex.printStackTrace();
//            }
//        }
//        return result;
//    }

    @Override
    public String toString() {
        return "RedisBloomFilter{" +
                "numApproxElements=" + numApproxElements +
                ", fpp=" + fpp +
                ", numHashFunctions=" + numHashFunctions +
                ", bitmapLength=" + bitmapLength +
                '}';
    }
}
